/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */

static double R22_sqrt[6][32] = {
  {0.921700, -0.000000, 0.010380, -0.027448, -0.250153, 0.294754, 0.005961, 0.010769, 0.010380, 0.027448, 0.921700, 0.000000, -0.011595, -0.004130, -0.250153, 0.294754, -0.250153, -0.294754, -0.011595, 0.004130, 0.921700, 0.000000, 0.010380, -0.027448, 0.005961, -0.010769, -0.250153, -0.294754, 0.010380, 0.027448, 0.921700, 0.000000},
  {0.923810, 0.000000, 0.004069, 0.027832, 0.151730, 0.350180, -0.009882, 0.006114, 0.004069, -0.027832, 0.923810, 0.000000, 0.011218, -0.003029, 0.151730, 0.350180, 0.151730, -0.350180, 0.011218, 0.003029, 0.923810, -0.000000, 0.004069, 0.027832, -0.009882, -0.006114, 0.151730, -0.350180, 0.004069, -0.027832, 0.923810, 0.000000},
  {0.927613, 0.000000, 0.014253, 0.025767, -0.061171, -0.367133, 0.009258, -0.007340, 0.014253, -0.025767, 0.927613, -0.000000, -0.011138, -0.003942, -0.061171, -0.367133, -0.061171, 0.367133, -0.011138, 0.003942, 0.927613, 0.000000, 0.014253, 0.025767, 0.009258, 0.007340, -0.061171, 0.367133, 0.014253, -0.025767, 0.927613, 0.000000},
  {0.869794, -0.000000, -0.010613, -0.001218, 0.399115, 0.289852, -0.004464, -0.004096, -0.010613, 0.001218, 0.869794, -0.000000, -0.005276, -0.002978, 0.399115, 0.289852, 0.399115, -0.289852, -0.005276, 0.002978, 0.869794, -0.000000, -0.010613, -0.001218, -0.004464, 0.004096, 0.399115, -0.289852, -0.010613, 0.001218, 0.869794, 0.000000},
  {0.919726, -0.000000, 0.038700, -0.111146, 0.217804, 0.300925, 0.045531, -0.013659, 0.038700, 0.111146, 0.919726, 0.000000, -0.027201, 0.038983, 0.217804, 0.300925, 0.217804, -0.300925, -0.027201, -0.038983, 0.919726, 0.000000, 0.038700, -0.111146, 0.045531, 0.013659, 0.217804, -0.300925, 0.038700, 0.111146, 0.919726, 0.000000},
  {0.867608, -0.000000, 0.194097, -0.112414, -0.418811, 0.095938, -0.081264, 0.075727, 0.194097, 0.112414, 0.867608, -0.000000, -0.106125, -0.032801, -0.418811, 0.095938, -0.418811, -0.095938, -0.106125, 0.032801, 0.867608, 0.000000, 0.194097, -0.112414, -0.081264, -0.075727, -0.418811, -0.095938, 0.194097, 0.112414, 0.867608, 0.000000},
};
static double R21_sqrt[6][8] = {
  {0.922167, 0.000000,-0.250280, 0.294903,-0.250280, -0.294903,0.922167, 0.000000},
  {0.924238, 0.000000,0.151801, 0.350342,0.151801, -0.350342,0.924238, 0.000000},
  {0.928080, 0.000000,-0.061202, -0.367318,-0.061202, 0.367318,0.928080, 0.000000},
  {0.869860, 0.000000,0.399145, 0.289874,0.399145, -0.289874,0.869860, 0.000000},
  {0.927225, 0.000000,0.219580, 0.303378,0.219580, -0.303378,0.927225, 0.000000},
  {0.896133, 0.000000,-0.432581, 0.099092,-0.432581, -0.099092,0.896133, 0.000000},
};
static double R12_sqrt[6][8] = {
  {0.999494, 0.000000,0.011256, -0.029765,0.011256, 0.029765,0.999494, 0.000000},
  {0.999537, 0.000000,0.004402, 0.030114,0.004402, -0.030114,0.999537, 0.000000},
  {0.999497, 0.000000,0.015358, 0.027764,0.015358, -0.027764,0.999497, 0.000000},
  {0.999925, -0.000000,-0.012201, -0.001400,-0.012201, 0.001400,0.999925, 0.000000},
  {0.991912, 0.000000,0.041738, -0.119870,0.041738, 0.119870,0.991912, 0.000000},
  {0.968169, 0.000000,0.216594, -0.125443,0.216594, 0.125443,0.968169, 0.000000},
};

// TS 38.104 - Table G.2.3.1.2-2: MIMO correlation matrices for high correlation
static double R22_high[4][4] = {
    {1.0, 0.9, 0.9, 0.81},
    {0.9, 1.0, 0.81, 0.9},
    {0.9, 0.81, 1.0, 0.9},
    {0.81, 0.9, 0.9, 1}
};
static double R24_high[8][8] = {
    {1.0000, 0.9883, 0.9542, 0.8999, 0.8999, 0.8894, 0.8587, 0.8099},
    {0.9883, 1.0000, 0.9883, 0.9542, 0.8894, 0.8999, 0.8894, 0.8587},
    {0.9542, 0.9883, 1.0000, 0.9883, 0.8587, 0.8894, 0.8999, 0.8894},
    {0.8999, 0.9542, 0.9883, 1.0000, 0.8099, 0.8587, 0.8894, 0.8999},
    {0.8999, 0.8894, 0.8587, 0.8099, 1.0000, 0.9883, 0.9542, 0.8999},
    {0.8894, 0.8999, 0.8894, 0.8587, 0.9883, 1.0000, 0.9883, 0.9542},
    {0.8587, 0.8894, 0.8999, 0.8894, 0.9542, 0.9883, 1.0000, 0.9883},
    {0.8099, 0.8587, 0.8894, 0.8999, 0.8999, 0.9542, 0.9883, 1.0000}
};
static double R44_high[16][16] = {
    {1.0000,    0.9882,    0.9541,    0.8999,    0.9882,    0.9767,    0.9430,    0.8894,    0.9541,    0.9430,    0.9105,    0.8587,    0.8999,    0.8894,    0.8587,    0.8099},
    {0.9882,    1.0000,    0.9882,    0.9541,    0.9767,    0.9882,    0.9767,    0.9430,    0.9430,    0.9541,    0.9430,    0.9105,    0.8894,    0.8999,    0.8894,    0.8587},
    {0.9541,    0.9882,    1.0000,    0.9882,    0.9430,    0.9767,    0.9882,    0.9767,    0.9105,    0.9430,    0.9541,    0.9430,    0.8587,    0.8894,    0.8999,    0.8894},
    {0.8999,    0.9541,    0.9882,    1.0000,    0.8894,    0.9430,    0.9767,    0.9882,    0.8587,    0.9105,    0.9430,    0.9541,    0.8099,    0.8587,    0.8894,    0.8999},
    {0.9882,    0.9767,    0.9430,    0.8894,    1.0000,    0.9882,    0.9541,    0.8999,    0.9882,    0.9767,    0.9430,    0.8894,    0.9541,    0.9430,    0.9105,    0.8587},
    {0.9767,    0.9882,    0.9767,    0.9430,    0.9882,    1.0000,    0.9882,    0.9541,    0.9767,    0.9882,    0.9767,    0.9430,    0.9430,    0.9541,    0.9430,    0.9105},
    {0.9430,    0.9767,    0.9882,    0.9767,    0.9541,    0.9882,    1.0000,    0.9882,    0.9430,    0.9767,    0.9882,    0.9767,    0.9105,    0.9430,    0.9541,    0.9430},
    {0.8894,    0.9430,    0.9767,    0.9882,    0.8999,    0.9541,    0.9882,    1.0000,    0.8894,    0.9430,    0.9767,    0.9882,    0.8587,    0.9105,    0.9430,    0.9541},
    {0.9541,    0.9430,    0.9105,    0.8587,    0.9882,    0.9767,    0.9430,    0.8894,    1.0000,    0.9882,    0.9541,    0.8999,    0.9882,    0.9767,    0.9430,    0.8894},
    {0.9430,    0.9541,    0.9430,    0.9105,    0.9767,    0.9882,    0.9767,    0.9430,    0.9882,    1.0000,    0.9882,    0.9541,    0.9767,    0.9882,    0.9767,    0.9430},
    {0.9105,    0.9430,    0.9541,    0.9430,    0.9430,    0.9767,    0.9882,    0.9767,    0.9541,    0.9882,    1.0000,    0.9882,    0.9430,    0.9767,    0.9882,    0.9767},
    {0.8587,    0.9105,    0.9430,    0.9541,    0.8894,    0.9430,    0.9767,    0.9882,    0.8999,    0.9541,    0.9882,    1.0000,    0.8894,    0.9430,    0.9767,    0.9882},
    {0.8999,    0.8894,    0.8587,    0.8099,    0.9541,    0.9430,    0.9105,    0.8587,    0.9882,    0.9767,    0.9430,    0.8894,    1.0000,    0.9882,    0.9541,    0.8999},
    {0.8894,    0.8999,    0.8894,    0.8587,    0.9430,    0.9541,    0.9430,    0.9105,    0.9767,    0.9882,    0.9767,    0.9430,    0.9882,    1.0000,    0.9882,    0.9541},
    {0.8587,    0.8894,    0.8999,    0.8894,    0.9105,    0.9430,    0.9541,    0.9430,    0.9430,    0.9767,    0.9882,    0.9767,    0.9541,    0.9882,    1.0000,    0.9882},
    {0.8099,    0.8587,    0.8894,    0.8999,    0.8587,    0.9105,    0.9430,    0.9541,    0.8894,    0.9430,    0.9767,    0.9882,    0.8999,    0.9541,    0.9882,    1.0000}
};

// TS 38.104 - Table G.2.3.1.2-3: MIMO correlation matrices for medium correlation
static double R22_medium[4][4] = {
    {1.0000, 0.9000, 0.3000, 0.2700},
    {0.9000, 1.0000, 0.2700, 0.3000},
    {0.3000, 0.2700, 1.0000, 0.9000},
    {0.2700, 0.3000, 0.9000, 1.0000}
};
static double R24_medium[8][8] = {
    {1.0000, 0.9884, 0.9543, 0.9000, 0.3000, 0.2965, 0.2863, 0.2700},
    {0.9884, 1.0000, 0.9884, 0.9543, 0.2965, 0.3000, 0.2965, 0.2863},
    {0.9543, 0.9884, 1.0000, 0.9884, 0.2863, 0.2965, 0.3000, 0.2965},
    {0.9000, 0.9543, 0.9884, 1.0000, 0.2700, 0.2863, 0.2965, 0.3000},
    {0.3000, 0.2965, 0.2863, 0.2700, 1.0000, 0.9884, 0.9543, 0.9000},
    {0.2965, 0.3000, 0.2965, 0.2863, 0.9884, 1.0000, 0.9884, 0.9543},
    {0.2863, 0.2965, 0.3000, 0.2965, 0.9543, 0.9884, 1.0000, 0.9884},
    {0.2700, 0.2863, 0.2965, 0.3000, 0.9000, 0.9543, 0.9884, 1.0000}
};
static double R44_medium[16][16] = {
    {1.0000, 0.9882, 0.9541, 0.8999, 0.8747, 0.8645, 0.8347, 0.7872, 0.5855, 0.5787, 0.5588, 0.5270, 0.3000, 0.2965, 0.2862, 0.2700},
    {0.9882, 1.0000, 0.9882, 0.9541, 0.8645, 0.8747, 0.8645, 0.8347, 0.5787, 0.5855, 0.5787, 0.5588, 0.2965, 0.3000, 0.2965, 0.2862},
    {0.9541, 0.9882, 1.0000, 0.9882, 0.8347, 0.8645, 0.8747, 0.8645, 0.5588, 0.5787, 0.5855, 0.5787, 0.2862, 0.2965, 0.3000, 0.2965},
    {0.8999, 0.9541, 0.9882, 1.0000, 0.7872, 0.8347, 0.8645, 0.8747, 0.5270, 0.5588, 0.5787, 0.5855, 0.2700, 0.2862, 0.2965, 0.3000},
    {0.8747, 0.8645, 0.8347, 0.7872, 1.0000, 0.9882, 0.9541, 0.8999, 0.8747, 0.8645, 0.8347, 0.7872, 0.5855, 0.5787, 0.5588, 0.5270},
    {0.8645, 0.8747, 0.8645, 0.8347, 0.9882, 1.0000, 0.9882, 0.9541, 0.8645, 0.8747, 0.8645, 0.8347, 0.5787, 0.5855, 0.5787, 0.5588},
    {0.8347, 0.8645, 0.8747, 0.8645, 0.9541, 0.9882, 1.0000, 0.9882, 0.8347, 0.8645, 0.8747, 0.8645, 0.5588, 0.5787, 0.5855, 0.5787},
    {0.7872, 0.8347, 0.8645, 0.8747, 0.8999, 0.9541, 0.9882, 1.0000, 0.7872, 0.8347, 0.8645, 0.8747, 0.5270, 0.5588, 0.5787, 0.5855},
    {0.5855, 0.5787, 0.5588, 0.5270, 0.8747, 0.8645, 0.8347, 0.7872, 1.0000, 0.9882, 0.9541, 0.8999, 0.8747, 0.8645, 0.8347, 0.7872},
    {0.5787, 0.5855, 0.5787, 0.5588, 0.8645, 0.8747, 0.8645, 0.8347, 0.9882, 1.0000, 0.9882, 0.9541, 0.8645, 0.8747, 0.8645, 0.8347},
    {0.5588, 0.5787, 0.5855, 0.5787, 0.8347, 0.8645, 0.8747, 0.8645, 0.9541, 0.9882, 1.0000, 0.9882, 0.8347, 0.8645, 0.8747, 0.8645},
    {0.5270, 0.5588, 0.5787, 0.5855, 0.7872, 0.8347, 0.8645, 0.8747, 0.8999, 0.9541, 0.9882, 1.0000, 0.7872, 0.8347, 0.8645, 0.8747},
    {0.3000, 0.2965, 0.2862, 0.2700, 0.5855, 0.5787, 0.5588, 0.5270, 0.8747, 0.8645, 0.8347, 0.7872, 1.0000, 0.9882, 0.9541, 0.8999},
    {0.2965, 0.3000, 0.2965, 0.2862, 0.5787, 0.5855, 0.5787, 0.5588, 0.8645, 0.8747, 0.8645, 0.8347, 0.9882, 1.0000, 0.9882, 0.9541},
    {0.2862, 0.2965, 0.3000, 0.2965, 0.5588, 0.5787, 0.5855, 0.5787, 0.8347, 0.8645, 0.8747, 0.8645, 0.9541, 0.9882, 1.0000, 0.9882},
    {0.2700, 0.2862, 0.2965, 0.3000, 0.5270, 0.5588, 0.5787, 0.5855, 0.7872, 0.8347, 0.8645, 0.8747, 0.8999, 0.9541, 0.9882, 1.0000}
};

// Matrices computed based on TS 38.104 - Tables G.2.3.1.1-3 and G.2.3.1.2-1
static double R12_medium_high[2][2] = {
    {1.0, 0.9},
    {0.9, 1.0}
};
static double R14_medium_high[4][4] = {
    {1.000000, 0.988362, 0.954253, 0.900000},
    {0.988362, 1.000000, 0.988362, 0.954253},
    {0.954253, 0.988362, 1.000000, 0.988362},
    {0.900000, 0.954253, 0.988362, 1.000000},
};
static double R18_medium_high[8][8] = {
    {1.000000, 0.997852, 0.991436, 0.980834, 0.966182, 0.947664, 0.925512, 0.900000},
    {0.997852, 1.000000, 0.997852, 0.991436, 0.980834, 0.966182, 0.947664, 0.925512},
    {0.991436, 0.997852, 1.000000, 0.997852, 0.991436, 0.980834, 0.966182, 0.947664},
    {0.980834, 0.991436, 0.997852, 1.000000, 0.997852, 0.991436, 0.980834, 0.966182},
    {0.966182, 0.980834, 0.991436, 0.997852, 1.000000, 0.997852, 0.991436, 0.980834},
    {0.947664, 0.966182, 0.980834, 0.991436, 0.997852, 1.000000, 0.997852, 0.991436},
    {0.925512, 0.947664, 0.966182, 0.980834, 0.991436, 0.997852, 1.000000, 0.997852},
    {0.900000, 0.925512, 0.947664, 0.966182, 0.980834, 0.991436, 0.997852, 1.000000}
};
